/****************************************************************************************
**  Filename :  ThinkTech_UART.c
**  Abstract :  This file implements SPI function.
**  By       :  钟伟
**  Date     :  2018-12-26 
**  Changelog:1.First Create
*****************************************************************************************/

/*****************************************************************************************
									Includes
*****************************************************************************************/
#include "ThinkTech_Pack.h"
#include "usart.h"
#include "delay.h"
#include "CRC16.h"
#include "w25qxx.h"
#include "key.h"
#include "SWD_flash.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "event_groups.h"
/*****************************************************************************************
								Variables definitions
*****************************************************************************************/
static UART_HandleTypeDef USART3Handler;

SerialFramingPacket packet;
updata_info_t updataInfo;
updata_info_t realUpdataInfo; 
ConfigInformation readConfigInformation;

uint8_t ACK[4] = { 0x5A, 0xA1, 0x00, 0x00 };
uint8_t NAK[4] = { 0x5A, 0xA2, 0x00, 0x00 };
uint8_t Abort[4] = { 0x5A, 0xA3, 0x00, 0x00 };
uint8_t uartTxBuf[USART3_REC_LEN]={0};
uint8_t uartRxBuf[USART3_REC_LEN];     
uint16_t uartRxSta = 0;
uint8_t receiveStartFlag = 0;
uint8_t receiveOverFlag = 0;
uint32_t receiveLen = 0;
uint16_t wait_cnt = 0;////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
uint32_t ConfigInformationLength = 0;

extern EventGroupHandle_t xEventGroupCreate_swd; 

void USART3_IRQHandler(void)
{
	u8 res;
	BaseType_t pd_ISR = pdFALSE;
	
	if (USART3->SR&(1<<5)) 
	{
		res = USART3->DR;
		uartRxBuf[uartRxSta] = res;
		if(uartRxBuf[0] == 0x5a)
		{
			receiveStartFlag = 1;
			xEventGroupSetBitsFromISR(xEventGroupCreate_swd, BIT_TASK_BIN, &pd_ISR);
		}
		
		if(receiveStartFlag == 1)
		{	
			uartRxSta++;
			if(uartRxSta == 6)
			{
				receiveLen = (((uint16_t)uartRxBuf[5]) << 8) | uartRxBuf[4] + 8;
			}
						
			if((uartRxSta > (USART3_REC_LEN-1)) | (uartRxSta == receiveLen))
			{
				uartRxSta = 0;
				receiveOverFlag = 1;
			}		
		}
		
	}
}

void usart3_init(void)
{
 	GPIO_InitTypeDef GPIO_Initure;   
	
	__HAL_RCC_USART3_CLK_ENABLE();
	__HAL_RCC_GPIOB_CLK_ENABLE();

	/**USART3 GPIO Configuration    
	PB10     ------> USART3_TX
	PB11     ------> USART3_RX 
	*/		
	
	GPIO_Initure.Pin = GPIO_PIN_10 | GPIO_PIN_11;		
	GPIO_Initure.Mode = GPIO_MODE_AF_PP;		
	GPIO_Initure.Pull = GPIO_PULLUP;			
	GPIO_Initure.Speed = GPIO_SPEED_HIGH;		
	GPIO_Initure.Alternate = GPIO_AF7_USART3;	
	HAL_GPIO_Init(GPIOB,&GPIO_Initure);	  
	
	USART3->CR1|=1<<5;    									// 接收缓冲区非空中断使能
	HAL_NVIC_EnableIRQ(USART3_IRQn);				
	HAL_NVIC_SetPriority(USART3_IRQn,5,1);	
	
	USART3Handler.Instance = USART3;
	USART3Handler.Init.BaudRate = USART3_BaudRate;
	USART3Handler.Init.WordLength = UART_WORDLENGTH_8B; 	// 字长为 8 位格式
	USART3Handler.Init.StopBits = UART_STOPBITS_1; 			// 一个停止位
	USART3Handler.Init.Parity = UART_PARITY_NONE; 			// 无奇偶校验位
	USART3Handler.Init.HwFlowCtl = UART_HWCONTROL_NONE; 	// 无硬件流控
	USART3Handler.Init.Mode = UART_MODE_TX_RX; 				// 收发模式 
	USART3Handler.Init.OverSampling = UART_OVERSAMPLING_16;
  HAL_UART_Init(&USART3Handler);
}

int MizarMsgEncode(SerialFramingPacket packet, uint8_t* buf)
{
	uint8_t* pTemp = buf;
	int len = 0;
	uint16_t crc16_temp;

	pTemp[len++] = packet.dataPacket.header.startByte;
	pTemp[len++] = packet.dataPacket.header.packetType;          
	pTemp[len++] = 0;
	pTemp[len++] = 0;
	pTemp[len++] = (uint8_t)packet.dataPacket.length;
	pTemp[len++] = (uint8_t)(packet.dataPacket.length >> 8);
	pTemp[len++] = 0;
	pTemp[len++] = 0;

	for (int i = 0; i < packet.dataPacket.length; i++)
	{
		pTemp[len++] = packet.data[i];
	}

	crc16_data_t crc16;
	crc16_init(&crc16);
	crc16_update(&crc16, pTemp, 6);
	crc16_update(&crc16, pTemp+8, (uint32_t)packet.dataPacket.length);
	crc16_finalize(&crc16, &crc16_temp);
	
	pTemp[6] = (uint8_t)crc16_temp;
	pTemp[7] = (uint8_t)(crc16_temp >> 8);

	return 0;
}

int MizarMsgDecode(SerialFramingPacket *packet, uint8_t* buf)
{
	uint8_t* pTemp = buf;
	uint16_t crc16_temp;

	packet->dataPacket.header.startByte = pTemp[0];
	packet->dataPacket.header.packetType = pTemp[1];         
	packet->dataPacket.reserved = (((uint16_t)pTemp[3]) << 8 | pTemp[2]);
	packet->dataPacket.length = (((uint16_t)pTemp[5]) << 8 | pTemp[4]);
	packet->dataPacket.crc16 = (((uint16_t)pTemp[7]) << 8 | pTemp[6]);

	for (int i = 0; i < packet->dataPacket.length; i++)
	{
		packet->data[i] = pTemp[8+i];
	}

	crc16_data_t crc16;
	crc16_init(&crc16);
	crc16_update(&crc16, pTemp, 6);
	crc16_update(&crc16, pTemp+8, (uint32_t)packet->dataPacket.length);
	crc16_finalize(&crc16, &crc16_temp);
	
	if (crc16_temp == packet->dataPacket.crc16)
		return 0;
	else
		return 1;
}

void my_uart_send(uint8_t* buff, uint16_t len)
{
	uint16_t sendNum = 0;
	if (buff == NULL || len == 0)
	{
		return;
	}
	
	while(sendNum < len)
	{
		while((USART3->SR&0X40)==0); 
		USART3->DR = *(buff + sendNum);
		sendNum++;
	}
	
	return;
}

void status_clean(void)
{
	for(int i = 0; i < sizeof(uartRxBuf); i++)
	{
		uartRxBuf[i] = 0;
	}
	uartRxSta = 0;				
	receiveStartFlag = 0;
	receiveOverFlag = 0;
	xEventGroupClearBits(xEventGroupCreate_swd, BIT_TASK_BIN);
}

void r_timeout(void)
{
	delay_us(100);
	wait_cnt++;
	if(wait_cnt == 5000)
	{
		wait_cnt = 0;
		
		if((uartRxBuf[0] == 0x5A) && (uartRxBuf[1] == 0xA6))
		{
			uint16_t crc16_buff;
			uartTxBuf[0] = 0x5A;
			uartTxBuf[1] = 0xA7;
			uartTxBuf[2] = 0x00;
			uartTxBuf[3] = 0x00;
			uartTxBuf[4] = 0x00;
			uartTxBuf[5] = 0x00;
			uartTxBuf[6] = 0x01;
			uartTxBuf[7] = 0x4D;
			
			crc16_data_t crc16;
			crc16_init(&crc16);
			crc16_update(&crc16, uartTxBuf, 8);
			crc16_finalize(&crc16, &crc16_buff);
			uartTxBuf[8] = (uint8_t)crc16_buff;
			uartTxBuf[9] = (uint8_t)(crc16_buff >> 8);
			
			my_uart_send(uartTxBuf, 10);
		}
		status_clean();
	}	
}

void wait_write_bin(void)
{
	int ret;
	static uint32_t flashStatusAddr, flashStartAddr;
	uint32_t lengthBuff;
	
	//接收超时处理函数
	r_timeout();
	
	//接收完毕处理
	if(receiveOverFlag == 1)
	{
		//CRC校验
		ret = MizarMsgDecode(&packet, uartRxBuf);
		
		if (ret == 0)//校验通过
		{	
			if((uartRxBuf[0] == 0x5A) && (uartRxBuf[1] == 0xA4)) //命令报文
			{										
				if(uartRxBuf[8] == 0x20) //写配置命令
				{
					W25QXX_Erase_Sector(Config_ADDRESS);
					W25QXX_Write(packet.data, Config_ADDRESS, packet.dataPacket.length);
					
					W25QXX_Read((u8*)&lengthBuff, Config_ADDRESS, 4);
					ConfigInformationLength = (uint8_t)(lengthBuff >> 24) * 4 + 4;
					W25QXX_Read((u8*)&readConfigInformation, Config_ADDRESS, ConfigInformationLength);
					
					my_uart_send(ACK, sizeof(ACK));
				}	
				else if(uartRxBuf[8] == 0x22) //读配置命令
				{
					W25QXX_Read((u8*)&lengthBuff, Config_ADDRESS, 4);
					ConfigInformationLength = (uint8_t)(lengthBuff >> 24) * 4 + 4;
					W25QXX_Read((u8*)&readConfigInformation, Config_ADDRESS, ConfigInformationLength);
					
					packet.dataPacket.header.startByte = 0x5a;
					packet.dataPacket.header.packetType = 0xa4;
					packet.dataPacket.length = (uint16_t)ConfigInformationLength;
					for (int i =0; i < ConfigInformationLength; i++)
						packet.data[i] = *((u8*)&readConfigInformation + i);
					MizarMsgEncode(packet, uartTxBuf);
					
					my_uart_send(uartTxBuf, packet.dataPacket.length + 8);
				}
				else if(uartRxBuf[8] == 0x21) //配置命令
				{
					if(uartRxBuf[12] == 0x01)
					{
						flashStatusAddr = FLASH_STATUS_ADDRESS_1;
						flashStartAddr = FLASH_START_ADDRESS_1;
					}
					else if(uartRxBuf[12] == 0x02)
					{
						flashStatusAddr = FLASH_STATUS_ADDRESS_2;
						flashStartAddr = FLASH_START_ADDRESS_2;
					}
					else if(uartRxBuf[12] == 0x03)
					{
						flashStatusAddr = FLASH_STATUS_ADDRESS_3;
						flashStartAddr = FLASH_START_ADDRESS_3;
					}
					else if(uartRxBuf[12] == 0x04)
					{
						flashStatusAddr = FLASH_STATUS_ADDRESS_4;
						flashStartAddr = FLASH_START_ADDRESS_4;
					}
					else if(uartRxBuf[12] == 0x05)
					{
						flashStatusAddr = FLASH_STATUS_ADDRESS_5;
						flashStartAddr = FLASH_START_ADDRESS_5;
					}
					else if(uartRxBuf[12] == 0x20)
					{
						flashStatusAddr = OTP_STATUS_ADDRESS_1;
						flashStartAddr = OTP_START_ADDRESS_1;
					}
					else if(uartRxBuf[12] == 0x21)
					{
						flashStatusAddr = OTP_STATUS_ADDRESS_2;
						flashStartAddr = OTP_START_ADDRESS_2;
					}
					
					updataInfo.totalNumber = (uint32_t)uartRxBuf[19] << 24;
					updataInfo.totalNumber |= (uint32_t)uartRxBuf[18] << 16;
					updataInfo.totalNumber |= (uint32_t)uartRxBuf[17] << 8;
					updataInfo.totalNumber |= (uint32_t)uartRxBuf[16];
					
					updataInfo.addTotalNumber = (uint32_t)uartRxBuf[23] << 24;
					updataInfo.addTotalNumber |= (uint32_t)uartRxBuf[22] << 16;
					updataInfo.addTotalNumber |= (uint32_t)uartRxBuf[21] << 8;
					updataInfo.addTotalNumber |= (uint32_t)uartRxBuf[20];
					
					updataInfo.blockByte = (uint32_t)uartRxBuf[27] << 24;
					updataInfo.blockByte |= (uint32_t)uartRxBuf[26] << 16;
					updataInfo.blockByte |= (uint32_t)uartRxBuf[25] << 8;
					updataInfo.blockByte |= (uint32_t)uartRxBuf[24];
					
					updataInfo.totalBlock = (uint32_t)uartRxBuf[31] << 24;
					updataInfo.totalBlock |= (uint32_t)uartRxBuf[30] << 16;
					updataInfo.totalBlock |= (uint32_t)uartRxBuf[29] << 8;
					updataInfo.totalBlock |= (uint32_t)uartRxBuf[28];
					
					updataInfo.endBlockNumber = (uint32_t)uartRxBuf[35] << 24;
					updataInfo.endBlockNumber |= (uint32_t)uartRxBuf[34] << 16;
					updataInfo.endBlockNumber |= (uint32_t)uartRxBuf[33] << 8;
					updataInfo.endBlockNumber |= (uint32_t)uartRxBuf[32];
					
					memset(&realUpdataInfo, 0, sizeof(updata_info_t));	
					
					W25QXX_Erase_Sector(flashStatusAddr);
					W25QXX_Write((u8*)&updataInfo, flashStatusAddr, sizeof(updata_info_t));		

					for (int i =0; i < updataInfo.totalNumber ; i = i + 4096)
					{
						W25QXX_Erase_Sector(flashStartAddr + i);
					}	
					
					my_uart_send(ACK, sizeof(ACK));
				}																			
			}	
			else if((uartRxBuf[0] == 0x5A) && (uartRxBuf[1] == 0xA5)) //数据报文
			{													
				realUpdataInfo.totalBlock += 1;
				
//					if (realUpdataInfo.totalBlock == 1)
//					{
//						for(int i = 0; i < packet.dataPacket.length; i++)
//							printf("packet.data[%d] = 0x%02x\r\n", i , packet.data[i]);
//					}
				
				if(realUpdataInfo.totalBlock <= updataInfo.totalBlock)
				{
					W25QXX_Write(packet.data, flashStartAddr + (realUpdataInfo.totalBlock-1)*updataInfo.blockByte, packet.dataPacket.length);
					
					W25QXX_Read(packet.data, flashStartAddr  + (realUpdataInfo.totalBlock-1)*updataInfo.blockByte, packet.dataPacket.length);
					
					realUpdataInfo.totalNumber += packet.dataPacket.length;
					
					for(int i = 0; i < packet.dataPacket.length; i++)
					{
						realUpdataInfo.addTotalNumber += packet.data[i];
					}
					
					if(realUpdataInfo.totalBlock == updataInfo.totalBlock)
					{
						if((realUpdataInfo.totalNumber == updataInfo.totalNumber) && (realUpdataInfo.addTotalNumber == updataInfo.addTotalNumber))
						{
							my_uart_send(ACK, sizeof(ACK));
						}	
						else
						{
							my_uart_send(NAK, sizeof(NAK));
						}	
					}
					else
					{
						my_uart_send(ACK, sizeof(ACK));			
					}				
				}															
			}
		}
		else
		{
			my_uart_send(NAK, sizeof(NAK));
		}
		
		status_clean();
	}	
}
/***********************************END OF FILE*******************************************/


